#pragma once
#include"Model.hpp"
#include"LoadBalancer.hpp"
#include"../comm/FileTools.hpp"
#include"../comm/log.hpp"
namespace Ns_Con
{
    using namespace Ns_Mod;
    using namespace Ns_Load;
    using namespace Ns_FileTools;
    using namespace Ns_Log;
    class Controler//负责实现业务逻辑
    {
    private:
        Model _model;//负责数据交互的模块
        LoadBalancer _lb;//负责负载均衡的模块
    public:
        Controler()
        {}
        ~Controler()
        {}
        
        bool get_question(int number,Question* out)
        {
            if(_model.getquestion(number,out))
            return true;
            else
            return false;
        }
        bool get_questions(vector<Question>* out)
        {
            if(_model.get_questions(out))
            return true;
            else
            return false;
        }
        bool get_latest_code(const string& cookie,const string& question_id,string& code)
        {
            string userid;
            get_userid_from_cookie(cookie,userid);
            if(_model.get_latest_code(userid,question_id,code))
            return true;
            else
            return false;
        }
        bool get_rank_data(vector<PersonRecord>& v)
        {
            if(!_model.get_rank_data(v))
            return false;
            else
            return true;
        }
        bool get_question_submit_record(const string& cookie,const string& question_id,vector<AnswerStatus>& v)
        {
            string userid;
            get_userid_from_cookie(cookie,userid);
            if(!_model.one_question_status(userid,question_id,v))
            return false;
            else
            return true;
        }
        
        void get_userid_from_cookie(const string& cookie,string& userid)
        {
            map<string,string> map=FileTools::parse_cookie(cookie);
            userid=map["userid"];
        }
        void get_password_from_cookie(const string& cookie,string& password)
        {
            map<string,string> map=FileTools::parse_cookie(cookie);
            password=map["password"];
        }
        bool check_cookie(const string& cookie)
        {
            string userid;
            get_userid_from_cookie(cookie,userid);
            string password;
            get_password_from_cookie(cookie,password);
            if(!userid.empty()&&!password.empty()&&_model.login(userid,password))
            return true;
            else
            return false;
        }
        void user_update_passed_question(const std::string& userid,const string& qid,int passed,int total)
        {
            if(passed==total)
            {
                _model.user_pass_question_update(userid,qid);
            }
        }
        void user_update_latest_answer_status(const string& userid,const string& question_id,const string& status,const string& code)
        {
            _model.user_pass_status_update(userid,question_id,status,code);
        }
        void judge_question(const string& userid,const string& qid,const string& code,string& passed_status,string& message)//题号，代码
        {
            //{ok/total,message}
            //获取测试用例
            vector<TestExample> tes;
            _model.get_test_examples(stoi(qid),tes);
            int total=tes.size();//总的测试用例个数
            int passed=0;//通过的测试用例个数
            //判题
            for(int i=0;i<total;i++)
            {
                string _stdin=tes[i]._stdin;
                int status;
                string judge_result;
                _lb.judge(code,_stdin,"1S","1MB",status,judge_result);
                if(status==0&&judge_result==tes[i]._stdout)
                passed++;
                else if(status==1)
                {
                    message=judge_result;
                    break;
                }
            }
            //更新用户是否通过这道题
            user_update_passed_question(userid,qid,passed,total);
            //更新用户最新的答题情况
            user_update_latest_answer_status(userid,qid,"AC",code);//写死了，todo
            //结果
            passed_status=to_string(passed)+"/"+to_string(total);
        }
        bool login(const string& userid,const string& password)
        {
            return _model.login(userid,password);
        }
        bool regist(const string& userid,const string& password,const string& gender,
        const string& age,const string& email,const string& name,const string& signature)
        {
            return _model.regist(userid,password,gender,age,email,name,signature);
        }
        bool test()
        {
            return true;
        }
    };
}